package tools

import (
	"encoding/binary"
	"io"
	"net"
)

//自定义数据格式的读写
/**
go处理字节序
type ByteOrder interface {
    Uint16([]byte) uint16
    Uint32([]byte) uint32
    Uint64([]byte) uint64
    PutUint16([]byte, uint16)
    PutUint32([]byte, uint32)
    PutUint64([]byte, uint64)
    String() string
}
前三个方法为读取值
后三个方法为写入值
*/

// Session 会话连接的结构体
type Session struct {
	conn net.Conn
}

// NewSession 构造方法
func NewSession(conn net.Conn) *Session {
	return &Session{
		conn: conn,
	}
}

// Write 向连接中写数据
func (s *Session) Write(data []byte) error {
	//首先声明一个字节切片 用来存储数据 该切片的长度为4个字节的header+数据的长度
	var buf = make([]byte, 4+len(data))
	//将数据的长度信息写入到头部的4个字节中
	binary.BigEndian.PutUint32(buf[:4], uint32(len(data)))
	//将数据写入到字节切片的第4位之后
	//copy(buf[4:], data)
	buf = append(buf[:4], data...)
	//写入数据
	_, err := s.conn.Write(buf)
	return err
}

//从连接中读数据
func (s *Session) Read() (data []byte, err error) {
	header := make([]byte, 4)
	_, err = io.ReadFull(s.conn, header)
	if err != nil {
		return nil, err
	}
	dataLength := binary.BigEndian.Uint32(header)
	data = make([]byte, dataLength)
	_, err = io.ReadFull(s.conn, data)
	if err != nil {
		return nil, err
	}
	return data, nil
}
